package vn.smartware.co.framework.swt.base;

import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;

import vn.smartware.co.framework.action.Requester;
import vn.smartware.co.framework.bean.LoginDTO;
import vn.smartware.co.framework.common.BaseConstant;
import vn.smartware.co.framework.exception.ClientException;
import vn.smartware.co.framework.exception.FatalException;
import vn.smartware.co.framework.exception.SessionTimeOutException;
import vn.smartware.co.framework.form.LoginForm;
import vn.smartware.co.framework.plugin.LangResources;
import vn.smartware.co.framework.utils.MsgBoxUtils;
import vn.smartware.co.java.net.commons.Utils;

/**
 * SWTRelogin
 * @author thuctt
 */
public class SWTRelogin extends JNetShell {

	private static Log log = LogFactory.getLog(SWTRelogin.class);
	
	private Button btnCancel;
	private Button btnLogin;
	private Button btnClear;
	private Text txtPassword;
	private Text txtUserName;
	private Group grpLoginInfo;

	private boolean isSessionTimeout = false;
	private static final int SIZE_X = 430;
	private static final int SIZE_Y = 215;
	private int loginNo = -1;
	
	/**
	 * Constructor
	 * @param parent
	 */
	public SWTRelogin(Shell parent) {
		super(parent, LangResources.getText("SWTRelogin.shell"), new Point(SIZE_X, SIZE_Y));
	}

	/* (non-Javadoc)
	 * @see vn.smartware.co.framework.swt.base.JNetShell#displaySearchCriteria()
	 */
	@Override
	protected void displaySearchCriteria() {
		isSessionTimeout = ((LoginForm)getSearchCriteria()).isSessionTimeout();
		if (isSessionTimeout){
			LoginDTO currUser = (LoginDTO)((LoginForm)getSearchCriteria()).getUserDTO();
			txtUserName.setEnabled(false);
			txtUserName.setText(Utils.toEmpty(currUser.getLoginName()));
			txtPassword.setFocus();
		}
	}

	/**
	 * Create contents of the dialog
	 */
	protected void initialize() {
		grpLoginInfo = new Group(this, SWT.NONE);
		grpLoginInfo.setBounds(10, 20, 400, 85);
		grpLoginInfo.setBackground(BaseConstant.COLOR_BGR_BASE);

		final CLabel clblUser = new CLabel(grpLoginInfo, SWT.SHADOW_OUT | SWT.CENTER);
		clblUser.setFont(BaseConstant.FONT_BASE_LABEL);
		clblUser.setBounds(14, 20, 120, 22);
		clblUser.setText(LangResources.getText("SWTRelogin.clblUser"));

		txtUserName = new Text(grpLoginInfo, SWT.BORDER);
		txtUserName.setTextLimit(30);
		txtUserName.setTabs(1);
		txtUserName.setFont(BaseConstant.FONT_BASE_TEXT);
		txtUserName.setBackground(BaseConstant.COLOR_TEXT_REQUIRED);
		txtUserName.setBounds(140, 20, 246, 22);
		txtUserName.addFocusListener(new FocusAdapter(){
			public void focusGained(FocusEvent arg0) {
				txtUserName.selectAll();
			}
		});

		final CLabel clblPassword = new CLabel(grpLoginInfo, SWT.SHADOW_OUT | SWT.CENTER);
		clblPassword.setFont(BaseConstant.FONT_BASE_LABEL);
		clblPassword.setBounds(14, 51, 120, 22);
		clblPassword.setText(LangResources.getText("SWTRelogin.clblPassword"));

		txtPassword = new Text(grpLoginInfo, SWT.PASSWORD | SWT.BORDER);
		txtPassword.setTextLimit(30);
		txtPassword.setTabs(2);
		txtPassword.setFont(BaseConstant.FONT_BASE_TEXT);
		txtPassword.setBackground(BaseConstant.COLOR_TEXT_NORMAL);
		txtPassword.setBounds(140, 51, 246, 22);
		txtPassword.addFocusListener(new FocusAdapter(){
			public void focusGained(FocusEvent arg0) {
				txtPassword.selectAll();
			}
		});

		btnClear = new Button(this, SWT.NONE);
		btnClear.setBounds(10, 115, 120, 23);
		btnClear.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnClear.setText(LangResources.getText("SWTRelogin.btnClear"));
		btnClear.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
		btnClear.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent arg0) {
				clearAction();
			}
		});

		btnLogin = new Button(this, SWT.NONE);
		btnLogin.setBounds(150, 115, 120, 23);
		setDefaultButton(btnLogin);
		btnLogin.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnLogin.setText(LangResources.getText("SWTRelogin.btnLogin"));
		btnLogin.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
		btnLogin.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent arg0) {
				loginAction();
			}
		});

		btnCancel = new Button(this, SWT.NONE);
		btnCancel.setBounds(290, 115, 120, 23);
		btnCancel.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnCancel.setText(LangResources.getText("SWTRelogin.btnCancel"));
		btnCancel.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
		btnCancel.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent arg0) {
				closeAction();
			}
		});
	}

	/**
	 * close action
	 *
	 */
	private void closeAction() {
		log.info("Close action.");
		this.dispose();
		if (isSessionTimeout){
			SWTBase baseForm = SWTManager.getInstance().getBaseManager();
			baseForm.exitAction(false);
		}
	}

	/**
	 * login action
	 *
	 */
	private void loginAction() {
		if (isErrors()){
			return;
		}
		try {
			if (!isSessionTimeout){
				LoginDTO user = LoginDTO.getInstance();
				if (user.getLoginName().equals(txtUserName.getText().trim())){
					MsgBoxUtils.warningMsgBox("warning.ACCOUNT_LOGINED", new Object[] { txtUserName.getText().trim() });
					txtUserName.setFocus();
					return;
				}
			}
			
			LoginForm form = new LoginForm();
			form.setActionForm("loginForm");
			form.setActionMethod("login");
			
			form.setUsername(Utils.toEmpty(txtUserName.getText()));
			form.setPassword(Utils.toEmpty(txtPassword.getText()));
			form.setLoginDate(new Date());
			form.setLoginIndex(this.loginNo);
			
			form = (LoginForm)Requester.execute(form);
			
			this.loginNo = form.getLoginIndex();
			
			if (form.isLoginSuccess()){
				this.dispose();
				((LoginForm)getSearchCriteria()).setUserChanged(true);
				((LoginForm)getSearchCriteria()).setUserDTO(form.getUserDTO());
				copyUserLoginInfo(form);
				((LoginForm)getSearchCriteria()).setSessionTimeout(false);
				
			}else{
				if (Utils.isNullEmpty(form.getLockOutDate())){
					if (form.getLoginTryNumber() < BaseConstant.MAX_LOGIN_NUMBER){
						MsgBoxUtils.errorMsgBox("errors.LOGING_ERROR",
								new Object[] { Integer.toString(BaseConstant.MAX_LOGIN_NUMBER) });
						
						if (isSessionTimeout){
							txtPassword.setFocus();
						}else{
							txtUserName.setFocus();
						}
						
					}else{
						MsgBoxUtils.errorMsgBox("errors.LOGING_ERROR_LOCK",
								new Object[] {Integer.toString(BaseConstant.MAX_LOGIN_NUMBER), form.getUsername()});
						
						grpLoginInfo.setEnabled(false);
						btnClear.setEnabled(false);
						btnLogin.setEnabled(false);
					}
				}else{
					MsgBoxUtils.errorMsgBox("errors.LOGING_ERROR_ACC_LOCKED",
									new Object[] {form.getUsername()});
					
					txtUserName.setFocus();
				}
				
			}
		
		} catch (SessionTimeOutException e) {
			log.warn("SessionTimeOutException.", e.getCause());
			loginAction();
			
		} catch (FatalException e) {
			MsgBoxUtils.fatalErrorMsgBox();
			e.printStackTrace();
		}
	}
	
	/**
	 * clear action
	 *
	 */
	protected void clearAction() {
		log.info("Clear action");
		txtUserName.setText("");
		txtPassword.setText("");
		if (isSessionTimeout){
			txtPassword.setFocus();
		}else{
			txtUserName.setFocus();
		}
	}
	
	/**
	 * check error
	 * @return boolean
	 */
	private boolean isErrors() {
		if (Utils.isNullEmpty(txtUserName.getText())){
			try {
				MsgBoxUtils.errorMsgBox("errors.NOT_NULL", new Object[]{"UserName"});
				txtUserName.setFocus();
				return true;
			} catch (ClientException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
	
	/**
	 * create all user login info
	 * @param form
	 */
	private void copyUserLoginInfo(LoginForm form) {
		LoginDTO clientUser = LoginDTO.getInstance();
		LoginDTO user = (LoginDTO)form.getUserDTO();
		try{
			BeanUtils.copyProperty(clientUser, "userId", new Integer(user.getUserId()));
			BeanUtils.copyProperty(clientUser, "loginName", user.getLoginName());
			BeanUtils.copyProperty(clientUser, "loginPass", user.getLoginPass());
			BeanUtils.copyProperty(clientUser, "name", user.getName());
			BeanUtils.copyProperty(clientUser, "initPrgId", user.getInitPrgId());
			
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}
